package com.coffee.excel.executor;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.coffee.excel.MochaExcelUtil;
import com.coffee.excel.metadata.MochaExportParameter;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.util.CellRangeAddress;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;

/**
 * 整个流程：
 *  1，在数据库建立一个字段表；
 *  2， 根据导出类型 展示可以导入的字段，下载时候可以让用户 选择需要下载的字段；【每个都有一个默认选项】
 *  3，根据选择的下载项目 组装 字段list (List<MochaExcelField>)
 *  4, 根据查询条件 查询数据 需要导出的数据
 *  5, 导出的数据流 写入文件系统；提供用户下载；
 *
 *       1，导出数据 支持 map<String, Object> key： 对应字段；
 *            class 必须是一个对象不能 使用对象引用； 普通查询 需要封装到一个类；
 *       2，合并单元格： 如果需要合并单元格， 封装类的时候 可以解析出 那些行 需要合并； 组装出 list<MergeRow>
 * 执行导出
 * @author: songkui
 * @since: 2023/2/14 10:51
 */
@Slf4j
public class ExportExcelExecutor<T> {

    private MochaExportParameter exportParameter;

    public ExportExcelExecutor(MochaExportParameter exportParameter){
        this.exportParameter = exportParameter;
    }

    public void doExport(List<T> data){

        ByteArrayOutputStream templateOutStream = null;
        ByteArrayInputStream templateInput = null;
        try {
            List<String> heads = exportParameter.getHead();
            List<List<String>> templateData = exportParameter.getTemplateList();

            templateOutStream = new ByteArrayOutputStream();
            EasyExcel.write(templateOutStream)
                    .registerWriteHandler(new HeadStyleWriteHandler(exportParameter.getHeadColorMap()))
                    .registerWriteHandler(new SimpleColumnWidthStyleStrategy(20))
                    .sheet(exportParameter.getTitleName())
                    .head(MochaExcelUtil.head(heads, exportParameter.getTitleName()))
                    .doWrite(templateData);
            byte[] buf = templateOutStream.toByteArray();
            templateOutStream.flush();
            templateOutStream.close();

            templateInput = new ByteArrayInputStream(buf);
            List<CellRangeAddress> mergeAddressList = exportParameter.getMergeAddressList();
            if (null == mergeAddressList || mergeAddressList.isEmpty()){
                EasyExcel.write(exportParameter.getOutputStream())
                        .withTemplate(templateInput)
                        .sheet()
                        .doFill(data);
            }else {
                EasyExcel.write(exportParameter.getOutputStream())
                        .withTemplate(templateInput)
                        .registerWriteHandler(new MochaMergeStrategy(mergeAddressList))
                        .sheet()
                        .doFill(data);
            }

        } catch (IOException e) {
            log.error("导出excel异常：", e);
        } finally {
            try {
                if (templateOutStream != null){
                    templateOutStream.close();
                }
                if (templateInput != null){
                    templateInput.close();
                }

            } catch (IOException e) {
                log.error("导出excel-关闭流异常：", e);
            }
        }
    }




}
